【第1367期】原来浏览器原生支持JS Base64编码解码
前言
看到这个的时候就先到业务场景,然后惊叹张老师是怎么发现这些的,有在想他又是如何去实践这些方法的,最后还有小工具的产出。今日早读文章由@张鑫旭授权分享。
正文从这开始~
一、基础不牢,选型糟糕
糟糕的技术选型往往源自自身技术广度不足。
就在数月前,一个前端HTML字符信息转Base64的需求,我是毫不犹豫去找了个开源的base64.js。
使用很简单,浏览器引入该JS文件,然后Base64编码这样:
Base64.encode('zhangxinxu');
// 返回:'emhhbmd4aW54dQ=='
解码就调用decode方法,如下:
Base64.decode('emhhbmd4aW54dQ==');
// 返回:'zhangxinxu'
数据准确,功能良好。当时弄完还洋洋得意,以为是个完美的解决。
结果,今天发现,尼玛原来浏览器很早就支持了JS Base64加密解密,而上面这种洋洋得意的做法完全就是瞎子点灯——白费蜡!根本就不是一个好的技术选型。
由于技术广度掌握不足,或者说JS基础掌握不牢,导致浪费了大把时间去找Base64的JS语言库,学习其API用法,换来一个冗余完全不需要加载的JS,现在来看,真是个糟糕的技术选型。
二、原生atob和btoa方法
实际上,从IE10+浏览器开始,所有浏览器就原生提供了Base64编码解码方法,不仅可以用于浏览器环境,Service Worker环境也可以使用。
方法名就是atob和btoa,具体语法如下:
1. Base64解码
语法为(浏览器中):
var decodedData = window.atob(encodedData);
或者(浏览器或js Worker线程中):
var decodedData = self.atob(encodedData);
例如:
window.atob('emhhbmd4aW54dQ==');
// 返回:'zhangxinxu'
结果如下图:
记住atob
atob这个方法名称乍一看,很奇怪,不知道这个单词什么意思。我们可以理解为 A to B,也就是从A到B。这里的B指的就是Base64吗?哈哈哈,恭喜你!猜错了!A指的才是Base64,反的,B才是普通字符,普通意思就是low,俗称low B。所以我们这么记忆,Low B,Low B,B表示很Low的普通字符,A才是Base64,和首字母对应关系是反的。
因此,atob表示Base64字符to普通字符,也就是Base64解码。
2. Base64编码
语法为(浏览器中):
var encodedData = window.btoa(stringToEncode);
或者(浏览器或js Worker线程中):
var encodedData = self.btoa(stringToEncode);
例如:
window.btoa('zhangxinxu');
// 返回:'emhhbmd4aW54dQ=='
结果如下图:
记住btoa方法
btoa这个方法名称乍一看,很奇怪,不知道这个单词什么意思。我们可以理解为 B to A,也就是从B到A。那B指什么,A指什么呢?和atob方法一样,B指的是low B普通字符串,A指的是Base64字符。
因此,btoa方法表示low B普通字符to Base64字符,也就是Base64编码。
补充于2018-08-09
有人提到中文Base64数据转换会有报错问题。
雾霜月同学提出了解决方法,就是中文先encode转码和decode编码:
window.btoa(window.encodeURIComponent('嘻嘻哈哈哈哈啦啦啦啦'));
window.decodeURIComponent(window.atob('JUU1JTk4JUJCJUU1JTk4JUJCJUU1JTkzJTg4JUU1JTkzJTg4JUU1JTkzJTg4JUU1JTkzJTg4JUU1JTk1JUE2JUU1JTk1JUE2JUU1JTk1JUE2JUU1JTk1JUE2'));
三、IE8/IE9的polyfill
当下,仍有不少PC项目还需要兼容IE9,所以,我们可以专门针对这些浏览器再引入一段ployfill脚本或者一个JS文件即可。
ployfill JS脚本戳这里,或者直接右键这里下载源文件!
实际使用,我们可以借助IE条件注释无缝对接。
也就是HTML中嵌入下面一段代码:
<!--[if IE]>
<script src="./base64-polyfill.js"></script>
<![endif]-->
[if IE]表示所有IE浏览器,由于IE10+浏览器已经放弃了著名的IE条件注释的支持,Chrome等浏览器本身就不支持这个IE私有语法,因此,很天然的,上面一段script引入只在IE9-浏览器下有效。而我们本来就希望只IE8,IE9浏览器引入ployfill,于是正好完美衔接上。
也就是原生支持atob和btoa方法的浏览器认为就是一段无需关心的HTML注释,不支持atob和btoa的IE9及其以下浏览器则会加载我们的base64-polyfill.js,使浏览器也支持window.btoa和window.atob这个语法。
在Chrome浏览器下,可以看到没有polyfill相关JS的加载:
而IE8原生不支持atob和btoa方法的浏览器也正常编码解码Base64字符了,如下截图:
四、任意文件Base64编码
借助FileReader对象和readAsDataURL方法,我们可以把任意的文件转换为Base64 Data-URI。假设我们的文件对象是file,则转换的JavaScript代码如下:
var reader = new FileReader();
reader.onload = function(e) {
// e.target.result就是该文件的完整Base64 Data-URI
};
reader.readAsDataURL(file);
基于此原理,我特意做了个简易小工具,可以得到任意文件的Base64 Data-URI,工具戳这里:base64.html
把对应的文件拖到工具页面任意位置即可。
例如一个只有’zhangxinxu’字符内容的txt文本拖进去可以得到:
可以看到文件的MIME type也自动识别出来了。然后base64,后面的关键内容数据会发现和执行btoa(‘zhangxinxu’)结果一模一样,都是’emhhbmd4aW54dQ==’,肯定必须要一样,不然我反而会怀疑自己哪里是不是弄错了。
此工具我用得很频繁,SVG转Base64,小尺寸图片转Base64,Woff字体转Base64,都是文件往里面一拖就搞定了,简单快捷。
此工具也是IE10+支持。
关于本文
作者:@张鑫旭
原文:
https://www.zhangxinxu.com/wordpress/2018/08/js-base64-atob-btoa-encode-decode/
最后,为你推荐
最后,看完这个,也利用了这两个方法做了一个基于姓名(中文转拼音->base64)生成密码的小工具来解脱平时给部门童鞋创建SVN账号的麻烦。